/*
 *  Copyright 2010, TERA Co., Ltd.  All right reserved.
 *
 *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF TERA CO.,
 *  LTD.  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED TO THIRD
 *  PARTIES, COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 *  WITHOUT THE PRIOR WRITTEN PERMISSION OF TERA CO., LTD
 *
 */
package com.tansun.rule.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.io.FileUtils;

/**
 * IOUtils
 * @author WY
 * @version 1.0
 */
public class IOUtils {

	/**
	 * read
	 * @param file	File
	 * @return	String
	 * @throws IOException	IOException
	 */
	public static String read(File file) throws IOException {
		return new String(getBytes(new FileInputStream(file)));
	}
	/**
	 * getStackTraceMsg
	 * @param e	Exception
	 * @return	String
	 */
	public static String getStackTraceMsg(Exception e) {
		StringWriter strWriter = new StringWriter();
		e.printStackTrace(new PrintWriter(strWriter));
		return strWriter.toString();
	}
	/**
	 * readJarResource
	 * @param fileName	fileName
	 * @param encoding	encoding
	 * @return	String
	 */
	public static String readJarResource(String fileName, String encoding) {
		String content = "";
		try {
			InputStream in = IOUtils.class.getResourceAsStream(fileName);
			content = IOUtils.read(in, encoding);
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return content;
	}
	/**
	 * read
	 * @param in	InputStream
	 * @param encoding	encoding
	 * @return	read
	 */
	public static String read(InputStream in, String encoding) {
		String content = "";
		try {
			BufferedReader bufReader = new BufferedReader(
					new InputStreamReader(in, encoding));
			String msg = "";
			while ((msg = bufReader.readLine()) != null) {
				content += msg;
			}
			bufReader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return content;
	}

	/**
	 * write
	 * @param file	File
	 * @param str	String
	 * @throws IOException	IOException
	 */
	public static void write(File file, String str) throws IOException {
		PrintWriter out = new PrintWriter(new FileWriter(file));
		out.print(str);
		out.close();
	}
	public static void write(File file, String str, String encoding) throws IOException {
		OutputStreamWriter outstream = new OutputStreamWriter(new FileOutputStream(file), encoding);
		PrintWriter out = new PrintWriter(outstream);
		out.print(str);
		out.close();
		outstream.close();
		out = null;
		outstream = null;
	}

	/**
	 * append
	 * @param file	File
	 * @param str	String
	 * @throws IOException	IOException
	 */
	public static void append(File file, String str) throws IOException {
		RandomAccessFile appFile = new RandomAccessFile(file, "rw");
		appFile.seek(appFile.length());
		appFile.write(str.getBytes());
		appFile.close();
	}

	/**
	 * getBytes
	 * @param input	InputStream
	 * @return	byte[]
	 * @throws IOException	IOException
	 */
	public static byte[] getBytes(InputStream input) throws IOException {
		int c;
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		while ((c = input.read()) != -1) {
			output.write(c);
		}
		input.close();
		output.close();
		return output.toByteArray();
	}

	/**
	 * getZipedBytes
	 * @param bytes	byte[]
	 * @return	byte[]
	 * @throws IOException	IOException
	 */
	public static byte[] getZipedBytes(byte[] bytes) throws IOException {
		ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
		GZIPOutputStream output = new GZIPOutputStream(byteOutput);
		output.write(bytes);
		output.close();
		return byteOutput.toByteArray();
	}

	/**
	 * getUnZippedBytes
	 * @param input	InputStream
	 * @return	byte[]
	 * @throws IOException	IOException
	 */
	public static byte[] getUnZippedBytes(InputStream input) throws IOException {
		return getBytes(new GZIPInputStream(input));
	}

	/**
	 * serializeWithZip
	 * @param object	Serializable
	 * @return	byte[]
	 * @throws IOException	IOException
	 */
	public static byte[] serializeWithZip(Serializable object)
			throws IOException {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		writeSerializeWithZip(object, output);
		output.close();
		return output.toByteArray();
	}

	/**
	 * serialize
	 * @param object	Serializable
	 * @return	byte[]
	 * @throws IOException	IOException
	 */
	public static byte[] serialize(Serializable object) throws IOException {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		writeSerialize(object, output);
		output.close();
		return output.toByteArray();
	}

	/**
	 * writeSerializeWithZip
	 * @param object	Serializable
	 * @param baos	OutputStream
	 * @throws IOException	IOException
	 */
	public static void writeSerializeWithZip(Serializable object,
			OutputStream baos) throws IOException {
		writeSerialize(object, new GZIPOutputStream(baos));
	}

	/**
	 * writeSerialize
	 * @param object	Serializable
	 * @param baos	OutputStream
	 * @throws IOException	IOException
	 */
	public static void writeSerialize(Serializable object, OutputStream baos)
			throws IOException {
		ObjectOutputStream output = new ObjectOutputStream(baos);
		output.writeObject(object);
	}

	/**
	 * deserializeWithUnzip
	 * @param bytes	byte[]
	 * @return	Object
	 * @throws IOException	IOException
	 * @throws ClassNotFoundException	ClassNotFoundException
	 */
	public static Object deserializeWithUnzip(byte[] bytes) throws IOException,
			ClassNotFoundException {
		return deserializeWithUnzip(new ByteArrayInputStream(bytes));
	}

	/**
	 * deserializeWithUnzip
	 * @param inputStream	InputStream
	 * @return	Object
	 * @throws IOException	IOException
	 * @throws ClassNotFoundException	ClassNotFoundException
	 */
	public static Object deserializeWithUnzip(InputStream inputStream)
			throws IOException, ClassNotFoundException {
		return deserialize(new GZIPInputStream(inputStream));
	}

	/**
	 * deserialize
	 * @param bytes	byte[]
	 * @return	Object
	 * @throws IOException	IOException
	 * @throws ClassNotFoundException	ClassNotFoundException
	 */
	public static Object deserialize(byte[] bytes) throws IOException,
			ClassNotFoundException {
		return deserialize(new ByteArrayInputStream(bytes));
	}

	/**
	 * deserialize
	 * @param inputStream	InputStream
	 * @return	Object
	 * @throws IOException	IOException
	 * @throws ClassNotFoundException	ClassNotFoundException
	 */
	public static Object deserialize(InputStream inputStream)
			throws IOException, ClassNotFoundException {
		ObjectInputStream input = new ObjectInputStream(inputStream);
		return input.readObject();
	}
	public static File createFile(String path, String fileName) {
		File file = new File(path + fileName);
		File parent = file.getParentFile();
		if (parent != null && !parent.exists()) {
			parent.mkdirs();
		}
		try {
			file.createNewFile();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return file;
	}
	public static String getLineByhead(File file, String head) {
		try {
			List<String> lines  = FileUtils.readLines(file, "UTF-8");
			for (String string : lines) {
				if(string.split(":")[0].equals(head)) {
					return string;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static String getFirstLineByPatternStr(String regex, String file){
		String line = null;
		try {
			InputStreamReader read = new InputStreamReader( new FileInputStream(file), "UTF-8");
			BufferedReader reader = new BufferedReader(read);
			try {
				while ((line = reader.readLine()) != null) {
					if(line.matches(regex)){
						break;
					}
				}
				reader.close();
				read.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return line;
	}
	public static boolean modifyFirstLineByPatternStr(String src, String regex, String file){
		StringBuffer strBuffer = new StringBuffer();
		String line = null;
		try {
			InputStreamReader read = new InputStreamReader( new FileInputStream(file), "UTF-8");
			BufferedReader reader = new BufferedReader(read);
			try {
				while ((line = reader.readLine()) != null) {
					if(line.matches(regex)){
						if(src != null && !src.equals("")){
							strBuffer.append(src+"\n");							
						}
					}else if(!"".equals(line.trim())){
						strBuffer.append(line+"\n");
					}
				}
				reader.close();
				read.close();
				read = null;
				reader = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return false;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		}
		try {
			OutputStream out  = new FileOutputStream(file);
			OutputStreamWriter osr = new OutputStreamWriter(out,"UTF-8");//���  
			BufferedWriter bufw = new BufferedWriter(osr);//����  
	        bufw.write(strBuffer.toString());  
	        bufw.flush();  
	        bufw.close();
	        out.close();
	        osr.close();
	        bufw = null;
	        osr = null;
	        out = null;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static boolean appendFileALine(String src, String file){

	        BufferedWriter out = null;     
	        try {     
	            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
	            out.newLine();
	            out.write(src);     
	        } catch (Exception e) {     
	            e.printStackTrace();
	        } finally {
	            try {     
	                if(out != null){  
	                    out.close();     
	                }  
	            } catch (IOException e) {     
	                e.printStackTrace();     
	            }     
	        }   
	        return true;
	}

    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        return dir.delete();
    }
}
